# app/management/commands/scheduler_status.py
from django.core.management.base import BaseCommand
from django.utils import timezone

from app.models import ScheduledTask, TaskExecutionLog, TaskMetrics
from utils.scheduler_manager import SchedulerManager


class Command(BaseCommand):
    help = '显示调度器和任务状态'
    
    def add_arguments(self, parser):
        parser.add_argument(
            '--task-id',
            type=int,
            help='显示特定任务的详细信息',
        )
        parser.add_argument(
            '--recent-logs',
            type=int,
            default=10,
            help='显示最近的执行日志数量，默认10条',
        )
        parser.add_argument(
            '--failed-only',
            action='store_true',
            help='只显示失败的任务日志',
        )
    
    def handle(self, *args, **options):
        if options['task_id']:
            self._show_task_details(options['task_id'], options['recent_logs'])
        else:
            self._show_overview(options['recent_logs'], options['failed_only'])
    
    def _show_overview(self, recent_logs_count, failed_only):
        """显示系统概览"""
        self.stdout.write(self.style.SUCCESS('📊 任务调度系统状态概览'))
        self.stdout.write('=' * 60)
        
        # 调度器状态
        scheduler_manager = SchedulerManager()
        scheduler_status = scheduler_manager.get_scheduler_status()
        
        self.stdout.write('📡 调度器状态:')
        if scheduler_status['running']:
            self.stdout.write(f"  状态: {self.style.SUCCESS('运行中')}")
        else:
            self.stdout.write(f"  状态: {self.style.ERROR('已停止')}")
        
        self.stdout.write(f"  活跃任务数: {scheduler_status['job_count']}")
        if scheduler_status['next_run_time']:
            self.stdout.write(f"  下次执行: {scheduler_status['next_run_time']}")
        
        self.stdout.write()
        
        # 任务统计
        total_tasks = ScheduledTask.objects.count()
        active_tasks = ScheduledTask.objects.filter(is_active=True).count()
        
        self.stdout.write('📋 任务统计:')
        self.stdout.write(f"  总任务数: {total_tasks}")
        self.stdout.write(f"  活跃任务: {active_tasks}")
        self.stdout.write(f"  暂停任务: {total_tasks - active_tasks}")
        
        self.stdout.write()
        
        # 执行统计
        total_executions = TaskExecutionLog.objects.count()
        completed_executions = TaskExecutionLog.objects.filter(
            status=TaskExecutionLog.StatusChoices.COMPLETED
        ).count()
        failed_executions = TaskExecutionLog.objects.filter(
            status=TaskExecutionLog.StatusChoices.FAILED
        ).count()
        running_executions = TaskExecutionLog.objects.filter(
            status=TaskExecutionLog.StatusChoices.RUNNING
        ).count()
        
        self.stdout.write('📈 执行统计:')
        self.stdout.write(f"  总执行次数: {total_executions}")
        self.stdout.write(f"  成功执行: {completed_executions}")
        self.stdout.write(f"  失败执行: {failed_executions}")
        self.stdout.write(f"  正在运行: {running_executions}")
        
        if total_executions > 0:
            success_rate = (completed_executions / total_executions) * 100
            self.stdout.write(f"  成功率: {success_rate:.2f}%")
        
        self.stdout.write()
        
        # 活跃任务列表
        self._show_active_tasks()
        
        # 最近执行日志
        self._show_recent_logs(recent_logs_count, failed_only)
    
    def _show_active_tasks(self):
        """显示活跃任务"""
        active_tasks = ScheduledTask.objects.filter(is_active=True).order_by('-last_run_time')
        
        self.stdout.write('🔄 活跃任务列表:')
        if not active_tasks:
            self.stdout.write('  暂无活跃任务')
            return
        
        self.stdout.write(
            f"  {'ID':<5} {'名称':<25} {'类型':<10} {'上次运行':<20} {'下次运行':<20}"
        )
        self.stdout.write('  ' + '-' * 85)
        
        for task in active_tasks[:10]:  # 只显示前10个
            last_run = task.last_run_time.strftime('%m-%d %H:%M:%S') if task.last_run_time else '从未运行'
            next_run = task.next_run_time.strftime('%m-%d %H:%M:%S') if task.next_run_time else '未知'
            
            self.stdout.write(
                f"  {task.id:<5} "
                f"{task.name[:25]:<25} "
                f"{task.trigger_type:<10} "
                f"{last_run:<20} "
                f"{next_run:<20}"
            )
        
        if active_tasks.count() > 10:
            self.stdout.write(f"  ... 还有 {active_tasks.count() - 10} 个任务")
        
        self.stdout.write()
    
    def _show_recent_logs(self, count, failed_only):
        """显示最近的执行日志"""
        logs_query = TaskExecutionLog.objects.order_by('-start_time')
        
        if failed_only:
            logs_query = logs_query.filter(status=TaskExecutionLog.StatusChoices.FAILED)
            title = f'❌ 最近 {count} 条失败日志:'
        else:
            title = f'📄 最近 {count} 条执行日志:'
        
        logs = logs_query[:count]
        
        self.stdout.write(title)
        if not logs:
            self.stdout.write('  暂无日志')
            return
        
        self.stdout.write(
            f"  {'任务名称':<25} {'状态':<8} {'开始时间':<16} {'耗时':<8} {'结果/错误':<30}"
        )
        self.stdout.write('  ' + '-' * 95)
        
        for log in logs:
            task_name = log.scheduled_task.name if log.scheduled_task else f"策略-{log.strategy_id}"
            task_name = task_name[:25]
            
            # 状态显示
            if log.status == TaskExecutionLog.StatusChoices.COMPLETED:
                status = self.style.SUCCESS('成功')
            elif log.status == TaskExecutionLog.StatusChoices.FAILED:
                status = self.style.ERROR('失败')
            elif log.status == TaskExecutionLog.StatusChoices.RUNNING:
                status = self.style.WARNING('运行中')
            else:
                status = log.get_status_display()
            
            start_time = log.start_time.strftime('%m-%d %H:%M:%S')
            
            # 执行时间
            if log.execution_time:
                duration = f"{log.execution_time:.2f}s"
            else:
                duration = "N/A"
            
            # 结果或错误信息
            if log.status == TaskExecutionLog.StatusChoices.FAILED and log.error_message:
                result_text = log.error_message[:30]
            elif log.result:
                result_text = str(log.result)[:30]
            else:
                result_text = ""
            
            self.stdout.write(
                f"  {task_name:<25} "
                f"{status:<8} "
                f"{start_time:<16} "
                f"{duration:<8} "
                f"{result_text:<30}"
            )
        
        self.stdout.write()
    
    def _show_task_details(self, task_id, recent_logs_count):
        """显示特定任务的详细信息"""
        try:
            task = ScheduledTask.objects.get(id=task_id)
        except ScheduledTask.DoesNotExist:
            self.stdout.write(
                self.style.ERROR(f'❌ 任务不存在: {task_id}')
            )
            return
        
        self.stdout.write(
            self.style.SUCCESS(f'📋 任务详细信息: {task.name}')
        )
        self.stdout.write('=' * 60)
        
        # 基本信息
        self.stdout.write('基本信息:')
        self.stdout.write(f"  ID: {task.id}")
        self.stdout.write(f"  名称: {task.name}")
        self.stdout.write(f"  描述: {task.description or '无'}")
        self.stdout.write(f"  状态: {'激活' if task.is_active else '暂停'}")
        self.stdout.write(f"  创建时间: {task.created_at}")
        self.stdout.write(f"  更新时间: {task.updated_at}")
        self.stdout.write()
        
        # 任务配置
        self.stdout.write('任务配置:')
        self.stdout.write(f"  模块路径: {task.module_path}")
        self.stdout.write(f"  函数名称: {task.function_name}")
        self.stdout.write(f"  参数: {task.args}")
        self.stdout.write(f"  关键字参数: {task.kwargs}")
        self.stdout.write(f"  最大实例数: {task.max_instances}")
        self.stdout.write()
        
        # 调度配置
        self.stdout.write('调度配置:')
        self.stdout.write(f"  触发器类型: {task.trigger_type}")
        self.stdout.write(f"  触发器配置: {task.trigger_config}")
        self.stdout.write(f"  上次运行: {task.last_run_time or '从未运行'}")
        self.stdout.write(f"  下次运行: {task.next_run_time or '未知'}")
        self.stdout.write()
        
        # 统计信息
        try:
            metrics = task.metrics
            self.stdout.write('统计信息:')
            self.stdout.write(f"  总执行次数: {metrics.total_executions}")
            self.stdout.write(f"  成功次数: {metrics.successful_executions}")
            self.stdout.write(f"  失败次数: {metrics.failed_executions}")
            self.stdout.write(f"  成功率: {metrics.success_rate:.2f}%")
            if metrics.avg_execution_time > 0:
                self.stdout.write(f"  平均执行时间: {metrics.avg_execution_time:.2f}秒")
                self.stdout.write(f"  最长执行时间: {metrics.max_execution_time:.2f}秒")
                self.stdout.write(f"  最短执行时间: {metrics.min_execution_time:.2f}秒")
            self.stdout.write()
        except TaskMetrics.DoesNotExist:
            self.stdout.write('统计信息: 暂无数据\n')
        
        # 最近执行日志
        recent_logs = task.execution_logs.all()[:recent_logs_count]
        if recent_logs:
            self.stdout.write(f'最近 {len(recent_logs)} 条执行日志:')
            self.stdout.write(
                f"  {'状态':<8} {'开始时间':<16} {'结束时间':<16} {'耗时':<8} {'结果/错误'}"
            )
            self.stdout.write('  ' + '-' * 80)
            
            for log in recent_logs:
                # 状态显示
                if log.status == TaskExecutionLog.StatusChoices.COMPLETED:
                    status = self.style.SUCCESS('成功')
                elif log.status == TaskExecutionLog.StatusChoices.FAILED:
                    status = self.style.ERROR('失败')
                elif log.status == TaskExecutionLog.StatusChoices.RUNNING:
                    status = self.style.WARNING('运行中')
                else:
                    status = log.get_status_display()
                
                start_time = log.start_time.strftime('%m-%d %H:%M:%S')
                end_time = log.end_time.strftime('%m-%d %H:%M:%S') if log.end_time else 'N/A'
                duration = f"{log.execution_time:.2f}s" if log.execution_time else "N/A"
                
                # 结果或错误信息
                if log.status == TaskExecutionLog.StatusChoices.FAILED and log.error_message:
                    result_text = log.error_message[:40]
                elif log.result:
                    result_text = str(log.result)[:40]
                else:
                    result_text = ""
                
                self.stdout.write(
                    f"  {status:<8} "
                    f"{start_time:<16} "
                    f"{end_time:<16} "
                    f"{duration:<8} "
                    f"{result_text}"
                )
        else:
            self.stdout.write('最近执行日志: 暂无数据')